#include <iostream>
#include<string>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <vector>
#include <fstream>
#include <stdio.h>

#include "sample_comm_nnie.h"
#include "sample_comm_ive.h"
#include "jpg2yuv_opencv.h"
#include "vgs_img.h"
#include "misc_util.h"

using namespace std;
using namespace cv;

HI_VOID jpg2yuv420(char* imgpath,char* yuvpath,unsigned int *Width, unsigned int *Height)              //yuv 420 sp (nv21) 切记！输入图像长宽必须是偶数
{   
    char* position;
    int cols,rows;
    memset_s(yuvpath, sizeof(*yuvpath), 0, sizeof(*yuvpath));
    strcpy(yuvpath,imgpath);
    position =strchr(yuvpath, '.');
    if(position)
    {
        memcpy(position + 1, "yuv",3);              //将路径的jpg改为yuv
    }
    else 
        return;
    // resize 图片到640*640
    Size dsize = Size(640, 640);
    cv::Mat Img = cv::imread(imgpath,3);
    cv::Mat Img_new;
	cv::resize(Img, Img_new, dsize, 0, 0, INTER_CUBIC);

    FILE  *fp = fopen(yuvpath,"wb");
    if (Img_new.empty())
    {
        std::cout << "empty!check your image";
        return;
    }
    cols = Img_new.cols;
    *Width   = Img_new.cols;
    rows = Img_new.rows;
    *Height  = Img_new.rows;

    int Yindex = 0;
    int UVindex = rows * cols;
    unsigned char* yuvbuff = (unsigned char *)malloc(rows*cols*1.5);
    cv::Mat NV21(rows+rows/2, cols, CV_8UC1);
    cv::Mat OpencvYUV;
    cv::Mat OpencvImg;
    cv::cvtColor(Img_new, OpencvYUV, COLOR_BGR2YUV_YV12);
    int UVRow{ 0 };
    for (int i=0;i<rows;i++)
    {
        for (int j=0;j<cols;j++)
        {
            uchar* YPointer = NV21.ptr<uchar>(i);

            int B = Img_new.at<cv::Vec3b>(i, j)[0];
            int G = Img_new.at<cv::Vec3b>(i, j)[1];
            int R = Img_new.at<cv::Vec3b>(i, j)[2];

            //计算Y的值
            int Y = (77 * R + 150 * G + 29 * B) >> 8;
            YPointer[j] = Y;
            yuvbuff[Yindex++] = (Y < 0) ? 0 : ((Y > 255) ? 255 : Y);
            uchar* UVPointer = NV21.ptr<uchar>(rows+i/2);
            //计算U、V的值，进行2x2的采样
            if (i%2==0&&(j)%2==0)
            {
                int U = ((-44 * R - 87 * G + 131 * B) >> 8) + 128;
                int V = ((131 * R - 110 * G - 21 * B) >> 8) + 128;
                UVPointer[j] = V;
                UVPointer[j+1] = U;
                yuvbuff[UVindex++] = (V < 0) ? 0 : ((V > 255) ? 255 : V);
                yuvbuff[UVindex++] = (U < 0) ? 0 : ((U > 255) ? 255 : U);
            }
        }
    }
    for (int i=0;i< 1.5 * rows * cols;i++)
    {
        fwrite(&yuvbuff[i], 1, 1, fp);
    }
    free(yuvbuff);
    fclose(fp);
    // cv::imshow("src", Img);//原图
    // cv::imshow("YUV", NV21);//转换后的图片
    // cv::imshow("opencv_YUV", OpencvYUV); //opencv转换后的图片
    // cv::imwrite("NV21.jpg", NV21);
    // cv::waitKey(30000);
}